function encodeBase64(str) {
  try {
    return btoa(unescape(encodeURIComponent(str)))
  } catch (_e) {
    return str
  }
}
function decodeBase64(str) {
  try {
    return decodeURIComponent(escape(atob(str)))
  } catch (_e) {
    return str
  }
}

export async function migrateStorage() {
  // Reserved for future schema migrations
}

export async function getFromStorage(key) {
  // 在某些开发场景（如非扩展环境或权限未声明前）chrome.storage 可能不可用
  if (
    typeof chrome === "undefined" ||
    !chrome.storage ||
    !chrome.storage.local
  ) {
    try {
      const raw = localStorage.getItem(key)
      try {
        const parsed = JSON.parse(raw)
        return parsed
      } catch (_e) {
        return raw
      }
    } catch (_e) {
      return undefined
    }
  }
  return new Promise((resolve) => {
    chrome.storage.local.get([key], (res) => resolve(res[key]))
  })
}

export async function saveToStorage(key, value) {
  if (
    typeof chrome === "undefined" ||
    !chrome.storage ||
    !chrome.storage.local
  ) {
    try {
      const data = typeof value === "string" ? value : JSON.stringify(value)
      localStorage.setItem(key, data)
    } catch (_e) {
      // ignore
    }
    return
  }
  return new Promise((resolve) => {
    chrome.storage.local.set({ [key]: value }, resolve)
  })
}

export async function exportAllData() {
  if (
    typeof chrome === "undefined" ||
    !chrome.storage ||
    !chrome.storage.local
  ) {
    try {
      const data = {}
      for (let i = 0; i < localStorage.length; i++) {
        const k = localStorage.key(i)
        data[k] = (() => {
          const raw = localStorage.getItem(k)
          try {
            return JSON.parse(raw)
          } catch (_e) {
            return raw
          }
        })()
      }
      return data
    } catch (_e) {
      return {}
    }
  }
  return new Promise((resolve) => {
    chrome.storage.local.get(null, (res) => resolve(res))
  })
}

export async function importAllData(obj) {
  if (
    typeof chrome === "undefined" ||
    !chrome.storage ||
    !chrome.storage.local
  ) {
    try {
      Object.keys(obj || {}).forEach((k) => {
        const v = obj[k]
        const data = typeof v === "string" ? v : JSON.stringify(v)
        localStorage.setItem(k, data)
      })
    } catch (_e) {
      // ignore
    }
    return
  }
  return new Promise((resolve) => {
    chrome.storage.local.set(obj, resolve)
  })
}

export function maybeEncrypt(value, enable) {
  if (!enable) return value
  try {
    return { __enc: true, v: encodeBase64(JSON.stringify(value)) }
  } catch (_e) {
    return value
  }
}

export function maybeDecrypt(value) {
  if (!value || value.__enc !== true) return value
  try {
    return JSON.parse(decodeBase64(value.v))
  } catch (_e) {
    return value
  }
}
